<?php
require_once 'Models/Cms/Service/CmsBaseService.php';

class CmsArticleService extends CmsBaseService {
	public function addCategory($fields) {
		return $this->getCategoryDao()->add($fields);
	}
	
	public function editCategory($id, $fields) {
		if ($id <= 0) return 0;
		return $this->getCategoryDao()->update($id, $fields);
	}
	
	public function deleteCategory($id) {
		return $this->getCategoryDao()->delete($id);
	}
	
	public function getCategory($id) {
		if ($id <= 0) return null;
		return $this->getCategoryDao()->get($id);
	}
	
	public function getCategoryByName($name) {
		if ($name == '') return null;
		return $this->getCategoryDao()->getByName($name);
	}
	
	public function listSubCategories($parentId) {
		return $this->getCategoryDao()->findByParentIdWithOrder($parentId);
	}
	
	public function listAllCategories() {
		$groups = array();
		foreach ($this->getCategoryDao()->findAll() as $category) {
			$groups[$category['parent_id']][$category['id']] = $category;
		}
		return $groups;
	}
	
	public function listTopCategories() {
		$topParentId = 0;
		return $this->listSubCategories($topParentId);
	}
	
	
	
	public function add($fields, $image) {
		if (empty($fields)) return 0;
		
		$fields['create_at'] = time();
		
		if (isset($image['tmp_name']) && !$image['error']) {
			$fields = $this->saveImage($image, $fields);
			$fields = $this->generateThumb($fields);
		}
		
		return $this->getArticleDao()->add($fields);
	}
	
	public function update($id, $fields, $image = array()) {
		if ($id <= 0 || !is_array($fields) || !count($fields)) return 0;
		$oldArticle = $this->get($id);
		if (empty($oldArticle)) return 0;
		
		$isUpdateImage = 0;
		if (isset($image['tmp_name']) && !$image['error']) {
			if ($oldArticle['image']) $this->removeOldImage(array($oldArticle['image'], $oldArticle['image_small']));
			$fields = $this->saveImage($image, $fields);
			$fields = $this->generateThumb($fields);
			$isUpdateImage = 1;
		}
		
		return $this->getArticleDao()->update($id, $fields) || $isUpdateImage;
	}
	
	public function get($id) {
		if ($id <= 0) return null;
		return $this->getArticleDao()->get($id);
	}
	
	public function delete($id) {
		if ($id <= 0) return 0;
		$oldArticle = $this->get($id);
		if (empty($oldArticle)) return 0;
		
		if ($oldArticle['image']) $this->removeOldImage(array($oldArticle['image'], $oldArticle['image_small']));
		
		return $this->getArticleDao()->delete($id);
	}
	
	public function listInPage($page, $perpage, $categoryId = 0) {
		$articles = array();
		$categories = $this->getCategoryDao()->findAll();
		$categoryIds = array();
		if ($categoryId) {
			foreach ($categories as $category) {
				if ($category['parent_id'] == $categoryId) $categoryIds[] = $category['id'];
			}
			if (!$categoryIds) $categoryIds[] = $categoryId;
		}
		
		foreach ($this->getArticleDao()->findInPage($page, $perpage, $categoryIds) as $article) {
			$article['category'] = !$categoryId && $categories[$article['category_id']]['parent_id'] ? $categories[$categories[$article['category_id']]['parent_id']] : $categories[$article['category_id']];
			$articles[] = $article;
		}
		return $articles;
	}
	
	
	
	
	private function saveImage($tmpImage, $article) {
		$config = $this->getAttachmentConfig();
		$subPath = $this->getSubDirectory();
		$this->makeDirectory($config['attachmentBasePath'], $subPath);
		
		$fileName = $this->generateImageFileName($article, $this->getFileExtendName($tmpImage['name']));
		$filePath = $config['attachmentBasePath'] . $subPath . $fileName;
		move_uploaded_file($tmpImage['tmp_name'], $filePath);
		$article['image'] = $config['attachmentBaseUrl'] . $subPath . $fileName;
		
		return $article;
	}
	
	private function generateThumb($article, $thumbWidth = 170, $thumbHeight = 170) {
		$config = $this->getAttachmentConfig();
		$subPath = $this->getSubDirectory();
		$this->makeDirectory($config['attachmentBasePath'], $subPath);
		
		$fileName = $this->generateImageFileName($article, 'jpg', $thumbWidth, $thumbHeight);
		$filePath = $config['attachmentBasePath'] . $subPath . $fileName;
		
		set_include_path(implode(PATH_SEPARATOR, array(realpath(APPLICATION_PATH . '/library/PEAR'), get_include_path())));
		require_once 'Image/Tools/Thumbnail.php';
		$options = array(
			'image' => file_get_contents($article['image']), 
			'width' => $thumbWidth, 
			'height' => $thumbHeight
		);
		
		$image = new Image_Tools_Thumbnail();
		$image->set($options);
        
        $image->save($filePath, IMAGETYPE_JPEG);
		
		$article['image_small'] = $config['attachmentBaseUrl'] . $subPath . $fileName;
		
		return $article;
	}
	
	private function removeOldImage($files) {
		$config = $this->getAttachmentConfig();
		$deletes = 0;
		foreach ($files as $file) {
			if (file_exists($config['publicPath'] . $file)) $deletes += unlink($config['publicPath'] . $file);
		}
		return $deletes;
	}
	
	private function getSubDirectory() {
		return date("Y/m/");
	}
	private function getAttachmentConfig() {
		return include(dirname(__FILE__) . '/../../../../configs/cms/attachment.php');
	}
	private function generateImageFileName($article, $extendName = 'jpg', $width = 0, $height = 0) {
		return md5($article['title'] . $article['description']) . ($width ? '_' . $width . 'x' . $height : '') . '.' . $extendName;
	}
	private function getFileExtendName($fileName) {
		$tmp = explode(".", $fileName);
		return count($tmp) > 1 ? $tmp[count($tmp) - 1] : 'jpg';
	}
	
	private function makeDirectory($base, $path) {
		$base = rtrim($base, '/');
		$path = trim(str_replace("\\", '/', $path), '/');
		$paths = explode('/', $path);
		
		if (is_dir($base . '/' . $path)) return ;
		
		$fullpath = $base;
		foreach ($paths as $segment) {
			$fullpath .= '/' . $segment;
			if (!is_dir($fullpath)) {
				mkdir($fullpath);
			}
		}
	}
	
	
	
	
	private function getCategoryDao() {
		require_once 'Models/Cms/Dao/CmsDaoFactory.php';
		return CmsDaoFactory::getInstance()->createCmsCategoryDao();
	}
	
	private function getArticleDao() {
		require_once 'Models/Cms/Dao/CmsDaoFactory.php';
		return CmsDaoFactory::getInstance()->createCmsArticleDao();
	}
}
